package com.quectel.util.kit;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 分页删除
 * <p>
 * 里边方法会向原先容器添加四个参数 limit offset pageNo pageSize
 *
 * @author: caolu
 * @email: louis.cao@quectel.com
 * @date: 2022-07-19 16:31:00
 */
@Slf4j
public class PageDeleteKit {

    private static final String LIMIT = "limit", OFFSET = "offset", PAGE_NO = "pageNo", PAGE_SIZE = "pageSize";

    private static final int DEFAULT_BATCH_DELETE_SIZE = 1000;

    /**
     * <pre>
     * 分页删除一定要有删除动作否则永远无法走出该方法
     * PageDeleteKit.pageDelete(rqs -> aiEventRecordService.queryList(rqs), conditions, this::batchDelete);
     * </pre>
     *
     * @param execFunction   查询条件表达式
     * @param originalParams 原始条件
     * @param deleteFunction 每一批数据的回调 需要在此方法删除
     * @param <T>
     */
    public static <T> void pageDelete(Function<Map<String, Object>, List<T>> execFunction, Map<String, Object> originalParams, Consumer<List<T>> deleteFunction) {
        pageDelete(execFunction, originalParams, DEFAULT_BATCH_DELETE_SIZE, deleteFunction);
    }

    /**
     * <pre>
     * 分页删除一定要有删除动作否则永远无法走出该方法
     * PageDeleteKit.pageDelete(rqs -> aiEventRecordService.queryList(rqs), conditions, this::batchDelete);
     * </pre>
     *
     * @param execFunction    查询条件表达式
     * @param originalParams  原始条件
     * @param batchDeleteSize 每次需要删除的数量（分页条数）
     * @param deleteFunction  每一批数据的回调 需要在此方法删除
     * @param <T>
     */
    public static <T> void pageDelete(Function<Map<String, Object>, List<T>> execFunction, Map<String, Object> originalParams, int batchDeleteSize, Consumer<List<T>> deleteFunction) {
        Map<String, Object> params = new HashMap<>(originalParams);
        // 永远只删除第一页
        params.put(OFFSET, 0);
        params.put(LIMIT, batchDeleteSize);

        params.put(PAGE_NO, 1);
        params.put(PAGE_SIZE, batchDeleteSize);

        while (true) {

            long t1 = System.currentTimeMillis();
            List<T> applyResult = execFunction.apply(params);
            long t2 = System.currentTimeMillis();
            log.debug("PageFetchKit fetch method. Current pageNo is {},pageSize:{},total cost {} ms, return records count is {}.",
                    1, PAGE_SIZE, t2 - t1, applyResult == null ? 0 : applyResult.size());

            if (CollectionUtils.isEmpty(applyResult)) {
                break;
            }
            deleteFunction.accept(applyResult);
            if (applyResult.size() < batchDeleteSize) {
                break;
            }
        }
    }


}
